#include "theaterconst.h"

/* TicketClerk */
void main() {
	int data;
	
	init();
	
	Acquire(idMutex);
	data = ReadMonitor(tcID, 0);
	prints("TicketClerk "); print(data); prints(" has entered the theater.\n");
	SetMonitor(tcID, 0, data + 1);
	Release(idMutex);
	while (1) {
		Acquire(tcLineLock);
		if (ReadMonitor(tcBreak, data) != 0) {
			/* go on a break. wake all customers */
			SetMonitor(tcState, data, C_BREAK);
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" is going on break.\n");
			/* Release(outputLock); */
			SetMonitor(tcBreakTime, data, ReadMonitor(tcBreakTime, data) + 1);
			SetMonitor(tcLineCount, data, 0);
			Broadcast(tcLineCV[data], tcLineLock);
			Wait(tcBreakCV, tcLineLock);
			SetMonitor(tcState, data, C_BUSY);
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" is comming off break.\n");
			/* Release(outputLock); */
			SetMonitor(tcBreak, data, 0);
		}
		if (ReadMonitor(tcLineCount, data) > 0) {
			/* there's someone in line. signal a customer */
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" has a line length "); print(ReadMonitor(tcLineCount, data));
			prints(" and is signaling a customer.\n");
			/* Release(outputLock); */
			SetMonitor(tcLineCount, data, ReadMonitor(tcLineCount, data) - 1);
			SetMonitor(tcState, data, C_BUSY);
			Signal(tcLineCV[data], tcLineLock);
		} else {
			/* no one in line. set ready */
			SetMonitor(tcState, data, C_READY);
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" has no one in line. I am available for a customer.\n");
			/* Release(outputLock); */
		}
		Acquire(tcLock[data]);
		Release(tcLineLock);
		Wait(tcCV[data],tcLock[data]);
		Acquire(tcLineLock);
		if (ReadMonitor(tcState, data) == C_BREAK) {
			Release(tcLock[data]);
			/* waken up by manager. go on a break */
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" is going on break.\n");
			/* Release(outputLock); */
			SetMonitor(tcBreakTime, data, ReadMonitor(tcBreakTime, data) + 1);
			Wait(tcBreakCV,tcLineLock);
			/* Acquire(outputLock); */
			prints("TicketClerk "); print(data); 
			prints(" is comming off break.\n");
			/* Release(outputLock); */
			SetMonitor(tcState, data, C_BUSY);
			SetMonitor(tcBreak, data, 0);
			Release(tcLineLock);
			continue;
		}
		Release(tcLineLock);
		/* interact with the head customer */
		SetMonitor(tcPrice, data, ReadMonitor(tcTicket, data) * TICKET_PRICE);
		/* Acquire(outputLock); */
		prints("TicketClerk "); print(data); 
		prints(" has an order for "); print(ReadMonitor(tcTicket, data));
		prints(" and the cost is $"); print(ReadMonitor(tcPrice, data));
		prints(".00.\n");
		/* Release(outputLock); */
		Signal(tcCV[data], tcLock[data]);
		Wait(tcCV[data], tcLock[data]);
	    /* get the money */
		Acquire(incomeMutex);
		SetMonitor(tcIncome, data, ReadMonitor(tcIncome, data) + ReadMonitor(tcPrice, data));
		SetMonitor(totalIncome, 0, ReadMonitor(totalIncome, 0) + ReadMonitor(tcPrice, data));
		Release(incomeMutex);
		Signal(tcCV[data], tcLock[data]);
		Wait(tcCV[data], tcLock[data]);
		Release(tcLock[data]);
	}
	Exit(0);
}